package com.ugoodtech.mdcc.client.controller;

import com.ugoodtech.mdcc.client.dto.ComplaintReportAnswer;
import com.ugoodtech.mdcc.client.dto.JsonResponse;
import com.ugoodtech.mdcc.client.service.ComplaintReportAuditService;
import com.ugoodtech.mdcc.client.service.ComplaintReportService;
import com.ugoodtech.mdcc.core.domain.User;
import com.ugoodtech.mdcc.core.dto.ComplaintSearch;
import com.ugoodtech.mdcc.core.repository.UserRepository;
import com.ugoodtech.mdcc.core.service.ComplaintKPIService;
import io.swagger.annotations.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.collections.map.LRUMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.security.Principal;
import java.util.List;

@Api(description = "投诉单相关接口")
@RestController
@RequestMapping("/complaintReport")
public class ComplaintReportController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(ComplaintReportController.class);

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private ComplaintReportService complaintReportService;

    @Autowired
    private ComplaintReportAuditService complaintReportAuditService;

    @Autowired
    private ComplaintKPIService complaintKPIService;
    // 给投诉报告处理上锁
    private LRUMap locks = new LRUMap(100);

    @ApiOperation("提交投诉单")
    @RequestMapping(value = "save", method = RequestMethod.POST, consumes = "application/json;charset=utf-8")
    public JsonResponse submitComplaintReport(@ApiIgnore Principal principal,
        @ApiParam("暂存:0 提交:1") @RequestParam(value = "submitType") Integer submitType,
        @ApiParam("投诉单答案") @RequestBody ComplaintReportAnswer complaintReportDataList,
        @ApiParam("暂存的投诉单ID") @RequestParam(value = "tempReportId", required = false) Long tempReportId) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        Lock lock = (Lock) locks.get(principal.getName());
        if (lock == null) {
            lock = (Lock) locks.put(principal.getName(), new ReentrantLock());
        }
        if (lock != null) {
            boolean tryLock = lock.tryLock();
            if (!tryLock) {
                return JsonResponse.errorResponseWithError("抱歉", "请勿重复操作!");
            }
        } else {
            return JsonResponse.errorResponseWithError("抱歉", "请勿重复操作!");
        }
        try {
            logger.info("提交的题目数量为:" + complaintReportDataList.getComplaintReportDataList().size());
            if (complaintReportDataList.getComplaintReportDataList().size() < 12) {
                return JsonResponse.errorResponseWithError("抱歉", "题目数量不正确");
            }
            if (submitType.equals(1)) {
                return complaintReportService
                    .submitComplaintReport(complaintReportDataList, clientUser, tempReportId);
            } else if (submitType.equals(0)) {
                return complaintReportService
                    .submitComplaintReportTemp(complaintReportDataList, clientUser, tempReportId);
            }
            return JsonResponse.errorResponseWithError("抱歉", "提交错误!" + submitType);
        } catch (Exception e) {
            log.warn("", e);
            return JsonResponse.errorResponseWithError("抱歉", "提交错误!" + submitType);
        }finally {
            lock.unlock();
        }
    }

    @ApiOperation("获取投诉报告审核")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页数", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "size", value = "每页条数", paramType = "query", dataType = "int"),
    })
    @RequestMapping(value = "getAuditComplaintReport", method = RequestMethod.POST)
    public JsonResponse getAuditComplaintReport(@ApiIgnore Principal principal, Pageable pageable,
        @ApiParam("未审核:0 已审核:1 返回投诉:2") @RequestParam(value = "reportStatus") Integer reportStatus,
        @ApiParam("投诉单筛选条件") @RequestBody ComplaintSearch complaintSearch) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        return complaintReportAuditService.getAuditComplaintReport(pageable, reportStatus, complaintSearch,clientUser);
    }

    @ApiOperation("获取投诉报告跟进")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页数", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "size", value = "每页条数", paramType = "query", dataType = "int"),
    })
    @RequestMapping(value = "getFollowComplaintReport", method = RequestMethod.POST)
    public JsonResponse getFollowComplaintReport(@ApiIgnore Principal principal, Pageable pageable,
        @ApiParam("待领取:0 处理中:1 已处理:2") @RequestParam(value = "reportStatus") Integer reportStatus,
        @ApiParam("投诉单筛选条件") @RequestBody ComplaintSearch complaintSearch) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        return complaintReportAuditService.getFollowComplaintReport(pageable, reportStatus, clientUser, complaintSearch);
    }

    @ApiOperation("审核指派投诉报告")
    @RequestMapping(value = "auditComplaintReport", method = RequestMethod.POST, consumes = "application/json;charset=utf-8")
    public JsonResponse auditComplaintReport(@ApiIgnore Principal principal,
        @ApiParam("有效时间") @RequestParam(value = "validTime") Long validTime,
        @ApiParam("投诉报告ID") @RequestParam(value = "complaintReportId") Long complaintReportId,
        @ApiParam("上级领导ID") @RequestParam(value = "leaderUser", required = false) Long leaderUser,
        @ApiParam("技术人员ID 逗号分隔") @RequestParam(value = "needFollowUserId", required = false) String needFollowUserId,
        @ApiParam("投诉单答案") @RequestBody ComplaintReportAnswer complaintReportDataList,
        @ApiParam("转派时的备注说明") @RequestParam(value = "otherFollowNode", required = false) String otherFollowNode) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        Lock lock = (Lock) locks.get(complaintReportId);
        if (lock == null) {
            lock = (Lock) locks.put(complaintReportId, new ReentrantLock());
        }
        if (lock != null) {
            boolean tryLock = lock.tryLock();
            if (!tryLock) {
                return JsonResponse.errorResponseWithError("抱歉", "请勿重复操作!");
            }
        } else {
            return JsonResponse.errorResponseWithError("抱歉", "请勿重复操作!");
        }
        try {
            return complaintReportAuditService
                .auditComplaintReport(clientUser, validTime, complaintReportId, leaderUser,
                    needFollowUserId, complaintReportDataList, otherFollowNode);
        } catch (Exception e) {
            return JsonResponse.errorResponseWithError("抱歉", "审核失败");
        }finally {
            lock.unlock();
        }
    }

    @ApiOperation("审核不通过投诉报告")
    @RequestMapping(value = "auditComplaintFalse", method = RequestMethod.GET)
    public JsonResponse auditComplaintFalse(@ApiIgnore Principal principal,
        @ApiParam("投诉报告ID") @RequestParam(value = "complaintReportId") Long complaintReportId,
        @ApiParam("审核不通过原因") @RequestParam(value = "auditNote") String auditNote) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        Lock lock = (Lock) locks.get(complaintReportId);
        if (lock == null) {
            lock = (Lock) locks.put(complaintReportId, new ReentrantLock());
        }
        if (lock != null) {
            boolean tryLock = lock.tryLock();
            if (!tryLock) {
                return JsonResponse.errorResponseWithError("抱歉", "请勿重复操作!");
            }
        } else {
            return JsonResponse.errorResponseWithError("抱歉", "请勿重复操作!");
        }
        try {
            return complaintReportAuditService.auditComplaintReportFalse(clientUser, auditNote, complaintReportId);
        } catch (Exception e) {
            return JsonResponse.errorResponseWithError("抱歉", "审核失败");
        }finally {
            lock.unlock();
        }
    }

    @ApiOperation("查询投诉报告列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页数", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "size", value = "每页条数", paramType = "query", dataType = "int"),
    })
    @RequestMapping(value = "getComplaintReport", method = RequestMethod.POST)
    public JsonResponse getComplaintReport(@ApiIgnore Principal principal, Pageable pageable,
        @ApiParam("投诉单筛选条件") @RequestBody ComplaintSearch complaintSearch) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        return complaintReportService.getComplaintReport(pageable, complaintSearch, clientUser);
    }

    @ApiOperation("获取自己提交的投诉报告")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页数", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "size", value = "每页条数", paramType = "query", dataType = "int"),
    })
    @RequestMapping(value = "getMyComplaintReport", method = RequestMethod.GET)
    public JsonResponse getMyComplaintReport(@ApiIgnore Principal principal, Pageable pageable) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        return complaintReportService.getMyComplaintReport(clientUser, pageable);
    }

    @ApiOperation("获取自己暂存的投诉报告")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "页数", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "size", value = "每页条数", paramType = "query", dataType = "int"),
    })
    @RequestMapping(value = "getMyTempComplaintReport", method = RequestMethod.GET)
    public JsonResponse getMyTempComplaintReport(@ApiIgnore Principal principal, Pageable pageable) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        return complaintReportService.getMyTempComplaintReport(clientUser, pageable);
    }

    @ApiOperation("删除暂存的投诉单")
    @RequestMapping(value = "deleteComplaintReport", method = RequestMethod.GET)
    public JsonResponse deleteComplaintReport(@ApiIgnore Principal principal, Long complaintTempReportId) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        return complaintReportService.deleteComplaintReport(clientUser, complaintTempReportId);
    }

    @ApiOperation("获取投诉单被指派的人")
    @RequestMapping(value = "getComplaintFollowUser", method = RequestMethod.GET)
    public JsonResponse getComplaintFollowUser(@ApiIgnore Principal principal, Long complaintReportId) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        return complaintReportService.getComplaintFollowUser(complaintReportId);
    }

    @ApiOperation("统计投诉报告KPI")
    @RequestMapping(value = "getComplaintKPI", method = RequestMethod.POST)
    public JsonResponse getComplaintKPI(@ApiIgnore Principal principal,
        @ApiParam("投诉单筛选条件") @RequestBody ComplaintSearch complaintSearch) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        Object object = complaintKPIService.statComplaint(complaintSearch, clientUser);
        return JsonResponse.successResponseWithData(object);
    }

    @ApiOperation("重新提交投诉报告")
    @RequestMapping(value = "save2", method = RequestMethod.POST)
    public JsonResponse submitComplaintReport_angin(@ApiIgnore Principal principal,
        @ApiParam("投诉报告ID") @RequestParam(value = "complaintReportId") Long complaintReportId,
        @ApiParam("投诉单答案") @RequestBody ComplaintReportAnswer complaintReportDataList) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        Lock lock = (Lock) locks.get(complaintReportId);
        if (lock == null) {
            lock = (Lock) locks.put(complaintReportId, new ReentrantLock());
        }
        if (lock != null) {
            boolean tryLock = lock.tryLock();
            if (!tryLock) {
                return JsonResponse.errorResponseWithError("抱歉", "请勿重复操作!");
            }
        } else {
            return JsonResponse.errorResponseWithError("抱歉", "请勿重复操作!");
        }
        try {
            return complaintReportService.submitComplaintReport_angin(complaintReportId, complaintReportDataList, clientUser);
        } catch (Exception e) {
            return JsonResponse.errorResponseWithError("抱歉", "审核失败");
        }finally {
            lock.unlock();
        }
    }

    @ApiOperation("放弃投诉报告")
    @RequestMapping(value = "giveUp", method = RequestMethod.GET)
    public JsonResponse giveUpReport(@ApiIgnore Principal principal,
        @ApiParam("投诉报告ID") @RequestParam(value = "complaintReportId") Long complaintReportId) {
        if (principal == null) {
            return JsonResponse.errorResponseWithError("抱歉", "invalid_token");
        }
        User clientUser = userRepository.findByUsername(principal.getName());
        if (clientUser == null) {
            return JsonResponse.errorResponseWithError("抱歉", "未找到此用户");
        }
        return complaintReportService.giveUpReport(complaintReportId);
    }

}
